part of '../widgets.dart';

typedef VanFieldTextAlign = VanHorizontalAlign;
typedef VanFieldArrowDirection = VanCellArrowDirection;
typedef VanFieldInputAlign = VanFieldTextAlign;
typedef VanFieldErrorMessageAlign = VanFieldTextAlign;

enum VanFieldType {
  text,
  tel,
  digit,
  number,
  password,
  textarea,
  url,
  email,
  datetime;

  TextInputType get keyboardType {
    if (tel == this) return TextInputType.phone;
    if (digit == this) return TextInputType.number;
    if (number == this) return const TextInputType.numberWithOptions(decimal: true);
    if (textarea == this) return TextInputType.multiline;
    if (url == this) return TextInputType.url;
    if (email == this) return TextInputType.emailAddress;
    if (datetime == this) return TextInputType.datetime;
    return TextInputType.text;
  }
}

enum VanFieldClearTrigger { focus, always }

enum VanFieldFormatTrigger { onChange, onBlur }

enum VanFieldLabelAlign {
  left,
  center,
  right,
  top;

  static get(dynamic value, {Type? type, String? tag, VanFieldLabelAlign? orElse}) {
    return parseEnum(value, values: values, type: type, tag: tag, orElse: orElse);
  }

  Alignment get alignment {
    if (this == center) return Alignment.center;
    if (this == right) return Alignment.centerRight;
    return Alignment.centerLeft;
  }

  MainAxisAlignment get mainAxisAlignment {
    if (this == center) return MainAxisAlignment.center;
    if (this == right) return MainAxisAlignment.end;
    return MainAxisAlignment.start;
  }

  VanCellLayout get layout {
    if (this == top) return VanCellLayout.vertical;
    return VanCellLayout.horizontal;
  }
}

class VanFieldAutoSizeConfig {
  final int? minRows;
  final int? maxRows;

  const VanFieldAutoSizeConfig({this.minRows, this.maxRows});

  static VanFieldAutoSizeConfig fromJson(Map<String, int> json) {
    return VanFieldAutoSizeConfig(minRows: json['minRows'], maxRows: json['maxRows']);
  }
}

class VanFieldValidateScope {
  final VanFieldValidationStatus status;
  final String message;

  const VanFieldValidateScope([
    this.status = VanFieldValidationStatus.unvalidated,
    this.message = "",
  ]);
}

class VanFieldValidateError {
  final String name;
  final String message;

  const VanFieldValidateError(this.name, this.message);

  @override
  String toString() {
    return "{ name: $name, message: $message }";
  }
}

class VanFieldController extends VanCtrl<String> {
  final List<_VanFieldState> _fields = [];

  VanFieldController(super.value);

  /// 	获取输入框焦点
  void focus() {
    for (var field in _fields) {
      field._focusNode.requestFocus();
    }
  }

  /// 取消输入框焦点
  void blur() {
    for (var field in _fields) {
      field._focusNode.unfocus();
    }
  }

  Future<VanFieldValidateError?> validate({List? rules}) async {
    for (var field in _fields) {
      var widget = field.widget;
      if (widget.name == null) return null;
      final name = widget.name!;
      final List rules0 = [];
      if (rules?.isNotEmpty == true) rules0.addAll(rules!);
      if (widget.rules?.isNotEmpty == true) rules0.addAll(widget.rules!);
      if (rules0.isEmpty) return null;
      for (var rule in rules0) {
        final message = await VanFieldRule.fromValid(rule, value).catchError((error) {
          String msg = "[$name]rule.valid.error";
          _logger.e(msg, error: error);
          return msg;
        });

        if (message?.isNotEmpty == true) {
          return VanFieldValidateError(name, message!);
        }
      }
    }
    return null;
  }

  void resetValidation() {
    for (var field in _fields) {
      if (field._form == null) continue;
      final errorInfo = field._form!._errorInfoRef.value;
      errorInfo.errors.removeWhere((d) => d.name == field.widget.name);
    }
  }

  VanFieldValidationStatus getValidationStatus() {
    for (var field in _fields) {
      if (field._form == null) continue;
      final status = field._form!._status.value;
      if (status[field.widget.name] != null) return status[field.widget.name]!;
    }
    return VanFieldValidationStatus.passed;
  }
}
